package com.tsj.spzx.cart.service.Impl;

import cn.hutool.core.collection.CollectionUtil;
import com.alibaba.fastjson.JSON;
import com.tsj.spzx.cart.service.CartService;
import com.tsj.spzx.client.feign.ProductFeignClient;
import com.tsj.spzx.model.entity.h5.CartInfo;
import com.tsj.spzx.model.entity.product.ProductSku;
import com.tsj.spzx.utils.AuthContextThreadLocalUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

@Service
public class CartServiceImpl implements CartService {

    /**
     * 数据以redis的hash形式存入redis  key为userId   field为商品skuId   value为商品sku信息
     */
    @Autowired
    private RedisTemplate<String, String> redisTemplate;
    private static final String PRE_CART_KEY = "user:cart:";
    @Autowired
    private ProductFeignClient productFeignClient;

    /**
     * 添加商品到购物车
     * @param skuId   商品skuId
     * @param skuNum  商品数量
     */
    @Override
    public void addToCart(Long skuId, Integer skuNum) {
        // 首先用户能将商品添加到购物车，说明用户已登录,先拿到用户的userId
        Long userId = AuthContextThreadLocalUtil.getUserInfo().getId();
        // 根据userId去判断这个商品是不是第一次加入购物车
        Object productSkuInfo = redisTemplate.opsForHash().get(PRE_CART_KEY + userId, String.valueOf(skuId));
        // 不为null，说明这个商品之前已经加入过购物车，只需要修改数量即可
        CartInfo cartInfo = null;
        if (productSkuInfo != null){
            // 将数据序列化为对象
            cartInfo = JSON.parseObject(productSkuInfo.toString(), CartInfo.class);
            // 修改数量
            cartInfo.setSkuNum(cartInfo.getSkuNum() + skuNum);
            cartInfo.setIsChecked(1);      // 已被添加至购物车，默认状态就是选中
            cartInfo.setUpdateTime(new Date());
        }else{
            // 为空，表示，这是第一次添加到购物车
            // todo: 需要远程调用 根据商品skuID获取商品sku信息
            cartInfo = new CartInfo();
            ProductSku productSku = productFeignClient.getBySkuId(skuId).getData();
            // 设置商品sku信息
            cartInfo.setUserId(userId);
            cartInfo.setSkuId(skuId);
            cartInfo.setSkuNum(skuNum);
            cartInfo.setCartPrice(productSku.getSalePrice());
            cartInfo.setImgUrl(productSku.getThumbImg());
            cartInfo.setSkuName(productSku.getSkuName());
            cartInfo.setIsChecked(1);
            cartInfo.setCreateTime(new Date());
            cartInfo.setUpdateTime(new Date());
        }

        // 商品存入redis中
        String cartInfoJson = JSON.toJSONString(cartInfo);
        redisTemplate.opsForHash().put(PRE_CART_KEY + userId, String.valueOf(skuId), cartInfoJson);
    }

    /**
     * 获取购物车列表
     * @return
     */
    @Override
    public List<CartInfo> cartList() {
        // 获取当前用户id
        Long userId = AuthContextThreadLocalUtil.getUserInfo().getId();
        List<Object> userInfoObjList = redisTemplate.opsForHash().values(PRE_CART_KEY + userId);
        if(!CollectionUtil.isEmpty(userInfoObjList)){
            List<CartInfo> cartInfoList = userInfoObjList.stream().map(userInfoObj ->
                    JSON.parseObject(userInfoObj.toString(), CartInfo.class))
                    .sorted((o1, o2) -> o2.getCreateTime().compareTo(o1.getCreateTime()))
                    .collect(Collectors.toList());
            return cartInfoList;
        }
        return new ArrayList<>();
    }

    /**
     * 根据skuId删除购物车商品
     * @param skuId
     */
    @Override
    public void deleteCart(Long skuId) {
        Long userId = AuthContextThreadLocalUtil.getUserInfo().getId();
        redisTemplate.opsForHash().delete(PRE_CART_KEY + userId, String.valueOf(skuId));
    }

    /**
     * 根据skuId更新商品选中状态
     * @param skuId
     * @param isChecked
     */
    @Override
    public void checkCart(Long skuId, Integer isChecked) {
        Long userId = AuthContextThreadLocalUtil.getUserInfo().getId();
        Boolean aBoolean = redisTemplate.opsForHash().hasKey(PRE_CART_KEY + userId, String.valueOf(skuId));
        if (aBoolean){
            // 存在这个商品
            Object userInfoObj = redisTemplate.opsForHash().get(PRE_CART_KEY + userId, String.valueOf(skuId));
            CartInfo cartInfo = JSON.parseObject(userInfoObj.toString(), CartInfo.class);
            cartInfo.setIsChecked(isChecked);
            redisTemplate.opsForHash().put(PRE_CART_KEY + userId, String.valueOf(skuId), JSON.toJSONString(cartInfo));
        }
    }

    /**
     * 更新购物车商品全选或者全不选
     * @param isChecked
     */
    @Override
    public void allCheckCart(Integer isChecked) {
        Long userId = AuthContextThreadLocalUtil.getUserInfo().getId();
        // 获取到购物车中所有的商品信息
        List<Object> userInfoObjList = redisTemplate.opsForHash().values(PRE_CART_KEY + userId);
        if (!CollectionUtil.isEmpty(userInfoObjList)){
            userInfoObjList.stream().map(userInfoObj ->{
                CartInfo cartInfo = JSON.parseObject(userInfoObj.toString(), CartInfo.class);
                cartInfo.setIsChecked(isChecked);
                return cartInfo;
            }).forEach(cartInfo -> {
                redisTemplate.opsForHash().put(PRE_CART_KEY + userId, String.valueOf(cartInfo.getSkuId()), JSON.toJSONString(cartInfo));
            });
        }
    }

    /**
     * 清空购物车
     */
    @Override
    public void clearCart() {
        Long userId = AuthContextThreadLocalUtil.getUserInfo().getId();
        redisTemplate.delete(PRE_CART_KEY + userId);
    }

    /**
     * 获取购物车中选中的商品信息
     * @return
     */
    @Override
    public List<CartInfo> getAllCkecked() {
        // 获取当前用户信息
        Long userId = AuthContextThreadLocalUtil.getUserInfo().getId();
        // 根据userId获取到该用户购物车的所有信息
        List<Object> userInfoObjList = redisTemplate.opsForHash().values(PRE_CART_KEY + userId);

        if (!CollectionUtil.isEmpty(userInfoObjList)){
            List<CartInfo> cartInfoList = userInfoObjList.stream()
                    .map(userInfoObj -> JSON.parseObject(userInfoObj.toString(), CartInfo.class))
                    // 等于1，表示他在购物车中选中
                    .filter(cartInfo -> cartInfo.getIsChecked() == 1)
                    .collect(Collectors.toList());
            return cartInfoList;
        }
        return new ArrayList<>();
    }

    /**
     * 删除购物车中选中的商品
     */
    @Override
    public void deleteCartChecked() {
        Long userId = AuthContextThreadLocalUtil.getUserInfo().getId();
        List<Object> cartInfoObjList = redisTemplate.opsForHash().values(PRE_CART_KEY + userId);
        cartInfoObjList.stream().map(cartInfoObj ->
                JSON.parseObject(cartInfoObj.toString(), CartInfo.class))
                .filter(cartInfo -> cartInfo.getIsChecked() == 1)
                .forEach(cartInfo -> {
                    redisTemplate.opsForHash().delete(PRE_CART_KEY + userId, String.valueOf(cartInfo.getSkuId()));
                });
    }

}
